package io.github.tesla.ops.system.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import io.github.tesla.ops.system.dao.MenuDao;
import io.github.tesla.ops.system.dao.RoleMenuDao;
import io.github.tesla.ops.system.domain.MenuDO;
import io.github.tesla.ops.system.domain.Tree;
import io.github.tesla.ops.system.service.MenuService;
import io.github.tesla.ops.utils.BuildTree;

@Service
@Transactional(readOnly = true, rollbackFor = Exception.class)
public class MenuServiceImpl implements MenuService {
  @Autowired
  MenuDao menuMapper;
  @Autowired
  RoleMenuDao roleMenuMapper;


  @Cacheable
  @Override
  public Tree<MenuDO> getSysMenuTree(Long id) {
    List<Tree<MenuDO>> trees = new ArrayList<Tree<MenuDO>>();
    List<MenuDO> menuDOs = menuMapper.listMenuByUserId(id);
    for (MenuDO sysMenuDO : menuDOs) {
      Tree<MenuDO> tree = new Tree<MenuDO>();
      tree.setId(sysMenuDO.getMenuId().toString());
      tree.setParentId(sysMenuDO.getParentId().toString());
      tree.setText(sysMenuDO.getName());
      Map<String, Object> attributes = new HashMap<>(16);
      attributes.put("url", sysMenuDO.getUrl());
      attributes.put("icon", sysMenuDO.getIcon());
      tree.setAttributes(attributes);
      trees.add(tree);
    }
    Tree<MenuDO> t = BuildTree.build(trees);
    return t;
  }

  @Override
  public List<MenuDO> list() {
    List<MenuDO> menus = menuMapper.list(new HashMap<String, Object>(16));
    return menus;
  }

  @Transactional(readOnly = false, rollbackFor = Exception.class)
  @Override
  public int remove(Long id) {
    int result = menuMapper.remove(id);
    return result;
  }

  @Transactional(readOnly = false, rollbackFor = Exception.class)
  @Override
  public int save(MenuDO menu) {
    int r = menuMapper.save(menu);
    return r;
  }

  @Transactional(readOnly = false, rollbackFor = Exception.class)
  @Override
  public int update(MenuDO menu) {
    int r = menuMapper.update(menu);
    return r;
  }

  @Override
  public MenuDO get(Long id) {
    MenuDO menuDO = menuMapper.get(id);
    return menuDO;
  }

  @Override
  public Tree<MenuDO> getTree() {
    List<Tree<MenuDO>> trees = new ArrayList<Tree<MenuDO>>();
    List<MenuDO> menuDOs = menuMapper.list(new HashMap<>(16));
    for (MenuDO sysMenuDO : menuDOs) {
      Tree<MenuDO> tree = new Tree<MenuDO>();
      tree.setId(sysMenuDO.getMenuId().toString());
      tree.setParentId(sysMenuDO.getParentId().toString());
      tree.setText(sysMenuDO.getName());
      trees.add(tree);
    }
    Tree<MenuDO> t = BuildTree.build(trees);
    return t;
  }

  @Override
  public Tree<MenuDO> getTree(Long id) {
    List<MenuDO> menus = menuMapper.list(new HashMap<String, Object>(16));
    List<Long> menuIds = roleMenuMapper.listMenuIdByRoleId(id);
    List<Long> temp = menuIds;
    for (MenuDO menu : menus) {
      if (temp.contains(menu.getParentId())) {
        menuIds.remove(menu.getParentId());
      }
    }
    List<Tree<MenuDO>> trees = new ArrayList<Tree<MenuDO>>();
    List<MenuDO> menuDOs = menuMapper.list(new HashMap<String, Object>(16));
    for (MenuDO sysMenuDO : menuDOs) {
      Tree<MenuDO> tree = new Tree<MenuDO>();
      tree.setId(sysMenuDO.getMenuId().toString());
      tree.setParentId(sysMenuDO.getParentId().toString());
      tree.setText(sysMenuDO.getName());
      Map<String, Object> state = new HashMap<>(16);
      Long menuId = sysMenuDO.getMenuId();
      if (menuIds.contains(menuId)) {
        state.put("selected", true);
      } else {
        state.put("selected", false);
      }
      tree.setState(state);
      trees.add(tree);
    }
    Tree<MenuDO> t = BuildTree.build(trees);
    return t;
  }

  @Override
  public List<Tree<MenuDO>> listMenuTree(Long id) {
    List<Tree<MenuDO>> trees = new ArrayList<Tree<MenuDO>>();
    List<MenuDO> menuDOs = menuMapper.listMenuByUserId(id);
    for (MenuDO sysMenuDO : menuDOs) {
      Tree<MenuDO> tree = new Tree<MenuDO>();
      tree.setId(sysMenuDO.getMenuId().toString());
      tree.setParentId(sysMenuDO.getParentId().toString());
      tree.setText(sysMenuDO.getName());
      Map<String, Object> attributes = new HashMap<>(16);
      attributes.put("url", sysMenuDO.getUrl());
      attributes.put("icon", sysMenuDO.getIcon());
      tree.setAttributes(attributes);
      trees.add(tree);
    }
    List<Tree<MenuDO>> list = BuildTree.buildList(trees, "0");
    return list;
  }

}
